﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MslDiary.Framework.Text
{
    public class CText
    {
        //图片正则
        private const string REG_IMG = "<img[^>]+src=\\s*(?:'(?<src>[^']+)'|\"(?<src>[^\"]+)\"|(?<src>[^>\\s]+))\\s*[^>]*>";

        #region 去除标签
        /// <summary>
        /// 过滤Html标记  保留p,img,br标记
        /// </summary>
        /// <param name="htmlCode">HTML字符串</param>
        /// <returns>得到包含p，img,br的HTML</returns>
        public static string ClearHtml(string htmlCode)
        {
            return ClearHtml(htmlCode, "p|img|br");
        }
        /// <summary>
        /// 过滤Html标记
        /// </summary>
        /// <param name="htmlCode">源码</param>
        /// <param name="leaveTags">保留标签，如：img|p|br|a</param>
        /// <returns></returns>
        public static string ClearHtml(string htmlCode, string leaveTags)
        {
            if (leaveTags != null && leaveTags != "")
            {
                //保留p,img,br标记   <(?!|p|img|br)(.[^>]*)>
                htmlCode = Regex.Replace(htmlCode, @"<(?!" + leaveTags + ")(.[^>]*)>", "", RegexOptions.IgnoreCase);
            }
            else
            {
                //去除所有HTML标签
                htmlCode = Regex.Replace(htmlCode, @"<(.[^>])*>", "");//@"<(\/\s*)?!?((\w+:)?\w+)(\w+(\s*=?\s*(([""'])(\\[""'tbnr]|[^\7])*?\7|\w+)|.{0})|\s)*?(\/\s*)?>",//清除所有html标签  
                htmlCode = htmlCode.Replace("<", "");
                htmlCode = htmlCode.Replace(">", "");
            }

            string[] Regexs ={
                                @"<script[^>]*?>.*?</script>",
                                @"([\r\n])[\s]+",
                                @"&(quot|#34);",
                                @"&(amp|#38);",
                                @"&(lt|#60);",
                                @"&(gt|#62);",
                                @"&(nbsp|#160);",
                                @"&(iexcl|#161);",
                                @"&(cent|#162);",
                                @"&(pound|#163);",
                                @"&(copy|#169);",
                                @"&#(\d+);",
                                @"-->",
                                @"<!--.*\n"
                            };

            string[] Replaces ={
                                "",
                                "",
                                "\"",
                                "&",
                                "<",
                                ">",
                                " ",
                                "\xa1", //chr(161),
                                "\xa2", //chr(162),
                                "\xa3", //chr(163),
                                "\xa9", //chr(169),
                                "",
                                "\r\n",
                                ""
                               };

            string s = htmlCode;
            for (int i = 0; i < Regexs.Length; i++)
            {
                s = Regex.Replace(s, Replaces[i], Regexs[i], RegexOptions.Multiline | RegexOptions.IgnoreCase);
            }
            return s;
        }
        /// <summary>
        /// 获得纯文本
        /// </summary>
        /// <param name="htmlCode">源码</param>
        /// <returns></returns>
        public static string GetTxt(string htmlCode)
        {
            string del = @"<head[^>]*>[\s\S]*?</head>";
            string content = Remove(htmlCode, del);

            del = @"(<script[^>]*>[\s\S]*?</script>)|(<IFRAME[^>]*>[\s\S]*?</IFRAME>)|(<style[^>]*>[\s\S]*?</style>|<title[^>]*>[\s\S]*?</title>|<meta[^>]*>|<option[^>]*>[\s\S]*?</option>)";
            content = Remove(content, del);
            del = @"(&nbsp;)|([\n\t]+)";
            content = Remove(content, del);
            string re = @"(<table(\s+[^>]*)*>)|(<td(\s+[^>]*)*>)|(<tr(\s+[^>]*)*>)|(<p(\s+[^>]*)*>)|(<div(\s+[^>]*)*>)|(<ul(\s+[^>]*)*>)|(<li(\s+[^>]*)*>)|</table>|</td>|</tr>|</p>|<br>|</div>|</li>|</ul>|<p />|<br />";
            content = Replace(content, re, "");
            content = Replace(content, @"[\f\n\r\v]+", "");
            content = Remove(content, @"<a(\s+[^>]*)*>[\s\S]*?</a>");
            content = Remove(content, "<[^>]+>");//去除各种HTML标记，获得纯内容
            content = content.Replace("\n", "");
            content = content.Replace("\r", "");
            content = content.Trim();
            return content;
        }

        #endregion

        #region 替换指定内容

        /// <summary>
        /// 替换指定内容
        /// </summary>
        /// <param name="input">输入内容</param>
        /// <param name="pattern">表达式字符串</param>
        /// <param name="replaceValue">替换值</param>
        /// <param name="groupIndex">分组序号, 0代表不分组</param>
        public static string Replace(string input, string pattern, string replaceValue, int groupIndex)
        {
            Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
            MatchCollection mcs = re.Matches(input);
            foreach (Match mc in mcs)
            {
                if (groupIndex > 0)
                {
                    input = input.Replace(mc.Groups[groupIndex].Value, replaceValue);
                }
                else
                {
                    input = input.Replace(mc.Value, replaceValue);
                }
            }
            return input;
        }
        /// <summary>
        /// 替换匹配的分组内容
        /// </summary>
        /// <param name="input">输入值</param>
        /// <param name="pattern">正则</param>
        /// <param name="replacement">使用指定的字符串替换匹配内容，若为空则替换成空字符串</param>
        /// 如：将“”日期：03/09/2014” 字符串中的日期替换成{yyyy-MM-dd}的样式，应该这样写：(注：${year}意思为分组名为year)
        /// ①Utility.Text.CRegex.Replace(input, @"(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})", "${year}-${month}-${day}");
        /// ②Utility.Text.CRegex.Replace(input, @"(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})", "$3-$1-$2");
        /// <returns></returns>
        public static string Replace(string input, string pattern, string replacement)
        {
            input = Regex.Replace(input, pattern, replacement, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
            return input;
        }
        /// <summary>
        /// 根据正则去除多余字符
        /// </summary>
        /// <param name="input">源码</param>
        /// <param name="pattern">正则</param>
        /// <returns></returns>
        public static string Remove(string input, string pattern)
        {
            return Replace(input, pattern, "");
        }
        #endregion

        /// <summary>
        /// 图片地址
        /// </summary>
        /// <param name="input">输入内容</param>
        public List<String> GetImgLinks(string input)
        {
            return GetList(input, REG_IMG, "src");
        }

        #region 多个匹配内容

        /// <summary>
        /// 多个匹配内容
        /// </summary>
        /// <param name="input">输入内容</param>
        /// <param name="pattern">表达式字符串</param>
        /// <param name="groupName">分组名, ""代表不分组</param>
        public List<string> GetList(string input, string pattern, string groupName)
        {
            List<string> list = new List<string>();
            Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);//| RegexOptions.IgnorePatternWhitespace
            MatchCollection mcs = re.Matches(input);
            foreach (Match mc in mcs)
            {
                if (groupName != "")
                {
                    list.Add(mc.Groups[groupName].Value);
                }
                else
                {
                    list.Add(mc.Value);
                }
            }
            return list;
        }

        /// <summary>
        /// 多个匹配内容
        /// </summary>
        /// <param name="input">输入内容</param>
        /// <param name="pattern">表达式字符串</param>
        /// <param name="groupIndex">第几个分组, 从1开始, 0代表不分组</param>
        public List<string> GetList(string input, string pattern, int groupIndex)
        {
            List<string> list = new List<string>();
            Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
            MatchCollection mcs = re.Matches(input);
            foreach (Match mc in mcs)
            {
                if (groupIndex > 0)
                {
                    list.Add(mc.Groups[groupIndex].Value);
                }
                else
                {
                    list.Add(mc.Value);
                }
            }
            return list;
        }
        #endregion

        /// <summary>
        /// 单个匹配内容
        /// </summary>
        /// <param name="input">输入内容</param>
        /// <param name="pattern">表达式字符串</param>
        /// <param name="groupIndex">第几个分组, 从1开始, 0代表不分组</param>
        public static string GetValueByGroupIndex(string input, string pattern, int groupIndex)
        {
            List<string> list = new List<string>();
            Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
            MatchCollection mcs = re.Matches(input);
            string tmp = String.Empty;
            foreach (Match mc in mcs)
            {
                tmp = mc.Value;
                if (groupIndex > 0)
                    tmp = mc.Groups[groupIndex].Value;
                break;
            }
            return tmp;
        }
    }
}
